package util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Getopt {
    private final String[] args;
    private final Map<String, String> options = new HashMap<>();
    private final List<String> nonOptions = new ArrayList<>();

    public Getopt(String[] args) {
        this.args = args;
        parseArgs();
    }

    private void parseArgs() {
        int i = 0;
        while (i < args.length) {
            String arg = args[i];
            if (arg.startsWith("--")) {
                // 这是一个长选项
                String optionName = arg.substring(2);
                String optionValue = null;
                int eqIndex = optionName.indexOf('=');
                if (eqIndex != -1) {
                    // 长选项带参数，形如 --option=value
                    optionName = optionName.substring(0, eqIndex);
                    optionValue = optionName.substring(eqIndex + 1);
                }
                options.put(optionName, optionValue);
            } else if (arg.startsWith("-")) {
                // 这是一个短选项
                for (int j = 1; j < arg.length(); j++) {
                    char optionChar = arg.charAt(j);
                    if (j + 1 < arg.length() && !Character.isWhitespace(arg.charAt(j + 1))) {
                        // 带参数的短选项，形如 -cvalue 或 -c=value（这里支持两种形式）
                        int nextCharIndex = j + 1;
                        if (arg.charAt(nextCharIndex) == '=') {
                            // -c=value 形式
                            String optionValue = arg.substring(nextCharIndex + 1);
                            options.put(String.valueOf(optionChar), optionValue);
                            break; // 跳出内层循环
                        } else if (Character.isLetterOrDigit(arg.charAt(nextCharIndex))) {
                            // -cvalue 形式（需要判断下一个字符是否是选项还是参数的一部分）
                            // 这里我们简单处理，认为-cvalue中的value是紧跟在c后面的字符序列
                            // 如果需要更复杂的处理，比如支持多个字符的参数，可以进一步修改
                            String optionValue = arg.substring(nextCharIndex);
                            options.put(String.valueOf(optionChar), optionValue);
                            break; // 跳出内层循环
                        }
                        // 如果既不是=也不是字母数字，则认为是无效的选项格式，抛出异常
                        throw new IllegalArgumentException("Invalid option format: " + arg);
                    } else {
                        // 不带参数的短选项，形如 -a
                        options.put(String.valueOf(optionChar), "");
                    }
                }
            } else {
                // 非选项参数
                nonOptions.add(arg);
            }
            i++; // 移动到下一个参数
        }
    }

    /**
     * 检查是否提供了某个选项。
     *
     * @param option 选项名，例如 "a" 对应 -a，"option" 对应 --option
     * @return 如果提供了该选项，则返回true
     */
    public boolean hasOption(String option) {
        return options.containsKey(option);
    }

    public String getOptionValue(String option) {
        return options.get(option);
    }

    /**
     * 检查是否提供了某个选项。
     * @param option 选项字符，例如 'a' 对应 -a
     * @return 如果提供了该选项，则返回true
     */
    public boolean hasOption(char option) {
        return options.containsKey(String.valueOf(option));
    }

    /**
     * 获取选项的参数值。
     * @param option 选项字符，例如 'c' 对应 -c value
     * @return 选项的参数值，如果选项不存在或没有参数，则返回null
     */
    public String getOptionValue(char option) {
        return options.get(String.valueOf(option));
    }

    /**
     * 获取所有非选项参数。
     * @return 非选项参数的列表
     */
    public List<String> getNonOptions() {
        return nonOptions;
    }

    public static void main(String[] args) {
        // 测试 Getopt
        Getopt getopt = new Getopt(new String[]{"-a", "-b", "-c", "value", "file.txt"});

        System.out.println("Has option a? " + getopt.hasOption('a'));
        System.out.println("Option c value: " + getopt.getOptionValue('c'));
        System.out.println("Non-options: " + getopt.getNonOptions());
    }
}
